/**
 * 
 */
package ads.engenharia.dal;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import ads.engenharia.entity.Course;
import ads.engenharia.entity.Discipline;
import ads.engenharia.entity.Professor;
import ads.engenharia.entity.Schedule;

/**
 * @author Lanedraex
 *
 */
public class DisciplineDAO {

	private String sql;
	private String tableName = "\"Discipline\"";
	private String tableSchedule = "\"Discipline_Schedule\"";
	private String tableDisciplineProfessor = "\"Discipline_Professor\"";

	private EntityManager em = new EntityManager() {

		@Override
		public Object treatResultSet(ResultSet resultSet) throws SQLException {
			Discipline discipline = new Discipline();
			discipline.id(resultSet.getInt("id"));
			discipline.name(resultSet.getString("name"));
			discipline.duration(resultSet.getInt("duration"));

			return discipline;
		}
	};

	/**
	 * 
	 * @param discipline
	 * @return
	 * @throws SQLException
	 */
	public Discipline save(Discipline discipline) throws SQLException {

		sql = " insert into "
				+ tableName
				+ " ( name, duration ) values ( ?, ? ) returning id, name, duration ";

		return (Discipline) em.getSingleResult(sql, discipline.name(),
				discipline.duration());
	}

	/**
	 * Deletes discipline.
	 * 
	 * @param discipline
	 * @throws SQLException
	 */
	public void delete(Discipline discipline) throws SQLException {

		sql = " delete from " + tableName + " where id = ? ";

		em.executeQuery(sql, discipline.id());
	}

	/**
	 * Deletes all disciplines.
	 * 
	 * @throws SQLException
	 */
	public void deleteAll() throws SQLException {

		sql = " delete from " + tableName;

		em.executeQuery(sql);
	}

	/**
	 * Updates discipline.
	 * 
	 * @param discipline
	 * @throws SQLException
	 */
	public void update(Discipline discipline) throws SQLException {

		sql = " update " + tableName
				+ " set name = ?, duration = ? where id = ? ";

		em.executeQuery(sql, discipline.name(), discipline.duration(),
				discipline.id());
	}

	/**
	 * Searches for discipline.
	 * 
	 * @param discipline
	 * @return discipline
	 * @throws SQLException
	 */
	public Discipline search(Discipline discipline) throws SQLException {

		sql = " select id, name, duration from " + tableName
				+ "  where id = ? ";

		return (Discipline) em.getSingleResult(sql, discipline.id());
	}

	/**
	 * Searches all disciplines.
	 * 
	 * @return List of disciplines
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Discipline> searchAll() throws SQLException {

		sql = " select id, name, duration from " + tableName;

		return (ArrayList<Discipline>) em.getResultList(sql);
	}

	/**
	 * 
	 * @param id
	 * @return
	 * @throws SQLException
	 */
	public Discipline searchById(int id) throws SQLException {

		sql = " select id, name, duration from " + tableName
				+ "  where id = ? ";

		return (Discipline) em.getSingleResult(sql, id);
	}

	/**
	 * 
	 * @return
	 * @throws SQLException
	 */
	public Discipline searchByMaxId() throws SQLException {

		sql = " select id, name, duration from " + tableName
				+ "  where id = ( select max(id) from " + tableName + " ) ";

		return (Discipline) em.getSingleResult(sql);
	}

	/**
	 * 
	 * @param name
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Discipline> searchByName(String name) throws SQLException {

		sql = " select id, name, duration from " + tableName
				+ "  where name = ? ";

		return (ArrayList<Discipline>) em.getResultList(sql, name);
	}

	/**
	 * 
	 * @param day
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Discipline> searchByDay(Schedule.Day day)
			throws SQLException {
		sql = " select distinct id, name, duration from " + tableName + " , "
				+ tableSchedule + " where day = ? and discipline_id = id ";

		return (ArrayList<Discipline>) em.getResultList(sql, day.value());
	}

	/**
	 * 
	 * @param time
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Discipline> searchByTime(Schedule.Time time)
			throws SQLException {

		sql = " select distinct id, name, duration from " + tableName + " , "
				+ tableSchedule + " where time = ? and discipline_id = id ";

		return (ArrayList<Discipline>) em.getResultList(sql, time.value());
	}

	/**
	 * 
	 * @param hour
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Discipline> searchByHour(Schedule.Hour hour)
			throws SQLException {

		sql = " select distinct id, name, duration from " + tableName + " , "
				+ tableSchedule + " where hour = ? and discipline_id = id ";

		return (ArrayList<Discipline>) em.getResultList(sql, hour.value());
	}

	/**
	 * 
	 * @param course
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Discipline> searchByCourse(Course course)
			throws SQLException {

		return null;
	}

	/**
	 * 
	 * @param professor
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Discipline> searchByProfessor(Professor professor)
			throws SQLException {

		sql = " select distinct id, name, duration from " + tableName + " , "
				+ tableDisciplineProfessor
				+ " where professor_id = ? and discipline_id = id ";

		return (ArrayList<Discipline>) em.getResultList(sql, professor.id());
	}

	/**
	 * Searches by discipline total duration.
	 * 
	 * @param duration
	 * @return List of disciplines
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Discipline> searchByDuration(int duration)
			throws SQLException {

		sql = " select id, name, duration from " + tableName
				+ "  where duration = ? ";

		return (ArrayList<Discipline>) em.getResultList(sql, duration);
	}
}
